﻿using System.Data;
using Core.Ndatax.Domain.Dto;
using Core.Ndatax.Domain.Ris;
using Core.Ndatax.Infrastructure.DBContext;
using Core.Ndatax.Infrastructure.Entitys;
using Dapper;
using Xman.Extensions.Core;

namespace Core.Ndatax.Domain
{
    public class BllRequest:IBllRequest
    {
        private readonly ILogger<BllRequest> _logger;
        private readonly ReservationDapper _dapper;


        public BllRequest(ILogger<BllRequest> logger, ReservationDapper dapper)
        {
            _logger = logger;
            _dapper = dapper;
        }

        public async Task AddRequestAsync(AddRequestDto input)
        {
            var tvpRequest = new List<TvpRequestInfo> { input.TvpRequest }.ToDataTable().AsTableValuedParameter("dbo.TVP_RequestInfo");
            var tvpRequestExam = input.TvpRequestsExamList.ToDataTable().AsTableValuedParameter("dbo.TVP_RequestExam");
            var tvpRequestFee = input.TvpRequestsFeeList.ToDataTable().AsTableValuedParameter("dbo.TVP_RequestFee");
            await _dapper.ExcuteCommandAsync("dbo.Proc_AddRequest", new { TVP_RequestInfo = tvpRequest, TVP_RequestExam = tvpRequestExam, TVP_RequestFee = tvpRequestFee }, commandType: CommandType.StoredProcedure);
        }

        public async Task UpdateRequestStateAsync(List<UpdateStateDto> inputs)
        {
            var sql = "Proc_UpdateState @SheetID,@StateType,@StateResult,@ExamDate,@ExamTime,@OperatorID,@OperatorName,@RequisitionID,@RequestDomain";
            _logger.LogInformation("执行的SQL参数："+ inputs.ToStringJoin());
            await _dapper.ExcuteCommandAsync(sql,inputs);
        }

        /// <summary>
        /// 新增/修改/取消预约信息
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<List<IBPExamRequestDto>> GetReservationDtoAsync(string sheetIds,string operateFlag)
        {
            var sql = $"Proc_GetReservationInfo '{sheetIds}','{operateFlag}'";
            _logger.LogInformation($"执行的SQL：{sql}");
            return (await _dapper.GetListAsync<IBPExamRequestDto>(sql)).ToList();
        }

        public async Task AddLogUploadResAsync(List<LogUploadRes> input)
        {
            var sql = "INSERT INTO Log_UploadRes(SheetID,SendBody,ResponseBody,SendTime,SendTo,SendStatus,SendCount)VALUES(@SheetID,@SendBody,@ResponseBody,@SendTime,@SendTo,@SendStatus,@SendCount)";
            await _dapper.ExcuteCommandAsync(sql, input);
        }

        public async Task<List<LogUploadRes>> GetLogUploadResListAsync()
        {
            var sql = $@"Proc_Ndatax_GetLogUploadRes";
            _logger.LogInformation($"执行的SQL语句：{sql}");

            var result = await _dapper.GetListAsync<LogUploadRes>(sql);
            return result.ToList();
        }

        public async Task UpdateLogUploadResAsync(List<LogUploadRes> input)
        {
            var sql = "UPDATE Log_UploadRes SET SendStatus=@SendStatus,SendTime=@SendTime,SendCount=SendCount+1,ResponseBody=@ResponseBody WHERE ID=@ID";
            await _dapper.ExcuteCommandAsync(sql, input);
        }

        public async Task<List<GetCheckInOrRegisterDto>> GetCheckInOrRegisterDtoAsync(List<string> sheetIdList, EnumRisOperateFlag flag)
        {
            var sheets = sheetIdList.ToStringJoin();
            var sql = $"Proc_Ndatax_GetCheckInOrRegisterInfo '{sheets}','{flag.To<int>()}'";
            _logger.LogInformation($"执行的SQL：{sql}");

            #region mapper对象
            var sourceDic = new Dictionary<string, GetCheckInOrRegisterDto>();

            GetCheckInOrRegisterDto mapper(RequestInfo request, RequestExam? exam, RequestFee? fee)
            {
                var key = request.SheetID + "--" + request.InPriorityLevel.ToString();
                if (!sourceDic.TryGetValue(key, out var outDto))
                {
                    outDto = new GetCheckInOrRegisterDto { RequestInfo = request };
                    sourceDic.Add(key, outDto);
                };

                if (exam != null)
                {
                    var findExam = outDto.RequestExamList.FirstOrDefault(t => t.SheetID == exam.SheetID && t.ItemCode == exam.ItemCode);
                    if (findExam == null)
                    {
                        outDto.RequestExamList.Add(exam);
                    }
                }

                if (fee != null)
                {
                    var findFee = outDto.RequestFeeList.FirstOrDefault(t => t.SheetID == fee.SheetID && t.FEEID == fee.FEEID);
                    if (findFee == null)
                    {
                        outDto.RequestFeeList.Add(fee);
                    }
                }

                return outDto;
            }
            #endregion

            var result = await _dapper.QueryAsync<RequestInfo, RequestExam, RequestFee, GetCheckInOrRegisterDto>(sql, mapper, splitOn: "ID,ID,ID");
            return result.Distinct().ToList();
        }

        public async Task<List<GetCancelRegisterDto>> GetCancelRegisterDtoAsync(List<string> sheetIdList)
        {
            var sheets = sheetIdList.ToStringJoin();
            var sql = $"Proc_Ndatax_GetCancelRegisterInfo '{sheets}'";
            _logger.LogInformation($"执行的SQL：{sql}");
            var result = await _dapper.GetListAsync<GetCancelRegisterDto>(sql);
            return result.ToList();
        }

    }
}
